package com.gsi.webstore.platform.storefront.pipelet.orderprocess;

import java.util.HashMap;
import java.util.Map;

import com.gsi.webstore.platform.adapter.storelocator.capi.StoreLocatorManager;
import com.gsi.webstore.platform.adapter.storelocator.internal.client.data.Storefront;
import com.gsi.webstore.platform.storefront.capi.shipping.GSIShippingBucketBO;
import com.intershop.beehive.core.capi.naming.NamingMgr;
import com.intershop.beehive.core.capi.pipeline.Pipelet;
import com.intershop.beehive.core.capi.pipeline.PipeletExecutionException;
import com.intershop.beehive.core.capi.pipeline.PipelineDictionary;
import com.intershop.beehive.core.capi.pipeline.PipelineInitializationException;
import com.intershop.beehive.core.capi.request.Request;
import com.intershop.sellside.appbase.b2c.capi.order.ProductLineItemBO;

/**
 * 
 */
public class MapStorefrontWithShippingBucketSet extends Pipelet
{

    /**
     * Constant used to access the pipeline dictionary with key 'ShippingBucketSet'
     */
    public static final String DN_SHIPPING_BUCKET_SET = "ShippingBucketSet";
    /**
     * Constant used to access the pipeline dictionary with key 'CurrentRequest'
     */
    public static final String DN_CURRENT_REQUEST = "CurrentRequest";
    /**
     * Constant used to access the pipeline dictionary with key 'StoreFrontWithLineItemMap'
     */
    public static final String DN_STORE_FRONT_WITH_LINE_ITEM_MAP = "StoreFrontWithLineItemMap";

    /**
     * The pipelet's execute method is called whenever the pipelets gets
     * executed in the context of a pipeline and a request. The pipeline
     * dictionary valid for the currently executing thread is provided as a
     * parameter.
     * 
     * @param dict
     *            The pipeline dictionary to be used.
     * @throws PipeletExecutionException
     *             Thrown in case of severe errors that make the pipelet execute
     *             impossible (e.g. missing required input data).
     */
    public int execute(PipelineDictionary dict) throws PipeletExecutionException
    {        
        // lookup 'CurrentRequest' in pipeline dictionary
        Request currentRequest = (Request)dict.get(DN_CURRENT_REQUEST);
        if (null == currentRequest)
        {
            throw new PipeletExecutionException("Mandatory input parameter 'CurrentRequest' not available in pipeline dictionary.");
        }
        // lookup 'ShippingBucketSet' in pipeline dictionary
        java.util.Set<GSIShippingBucketBO> shippingBucketSet = (java.util.Set)dict.get(DN_SHIPPING_BUCKET_SET);
        if (null == shippingBucketSet)
        {
            throw new PipeletExecutionException("Mandatory input parameter 'ShippingBucketSet' not available in pipeline dictionary.");
        }
        
        Long storeId = null;
        Storefront storeFront;
        Map<Long, Storefront> storeFrontMap = new HashMap<Long, Storefront>();
        Map<String, Storefront> storefrontByLineItemMap = new HashMap<String, Storefront>();

        String localeId = currentRequest.getLocale().getLocaleID();
        for (GSIShippingBucketBO bucket : shippingBucketSet) {
            for (ProductLineItemBO lineItem : bucket.getProductLineItemBOs()) {
                storeId = (Long)lineItem.getCustomAttributes().getAttribute(STOREFRONT_ID_ATTRIBUTE_NAME);
                if (storeId != null)
                {
                    if (storeFrontMap.get(storeId) == null)
                    {
                            storeFront = storeLocatorMgr.getStorefront(storeId, localeId);
                            storeFrontMap.put(storeId, storeFront);
                    }
                    else
                    {
                            storeFront = storeFrontMap.get(storeId);
                    }
                    storefrontByLineItemMap.put(lineItem.getID(), storeFront);
                }
            }
        }

        dict.put(DN_STORE_FRONT_WITH_LINE_ITEM_MAP, storefrontByLineItemMap);
        return PIPELET_NEXT;
    }
    
    public void init() throws PipelineInitializationException
    {
        storeLocatorMgr = (StoreLocatorManager)NamingMgr.getManager(StoreLocatorManager.class);
    }
    
    private StoreLocatorManager storeLocatorMgr = null;
    private static final String STOREFRONT_ID_ATTRIBUTE_NAME = "STORE_ID";
}